package ctp.md;

import ctp.thostapi.*;

/**
 * 自定义TradeSpi类，实现登陆、行情订阅等回调功能
 */
public class MyMdSpi extends CThostFtdcMdSpi {
    private final MyMdApi m_mdapi;

    MyMdSpi(MyMdApi mdapi) {
        m_mdapi = mdapi;
    }

    /**
     * 当客户端与交易托管系统通信连接断开时，该方法被调用。
     *
     */
    @Override
    public void OnFrontDisconnected(int nReason) {
        System.out.println("On Front Disconnected " + Integer.toHexString(nReason));
    }

    /**
     * 当客户端与交易托管系统建立起通信连接时（还未登录前），该方法被调用。
     * 本方法在完成初始化后调用，可以在其中完成用户认证。
     */
    @Override
    public void OnFrontConnected() {
        System.out.println("On Front Connected");
        m_mdapi.ReqUserLogin();     //用户登陆
    }

    /**
     * 登录请求响应，当执行ReqUserLogin后，该方法被调用。
     * 可以在其中订阅行情。
     */
    @Override
    public void OnRspUserLogin(CThostFtdcRspUserLoginField pRspUserLogin, CThostFtdcRspInfoField pRspInfo, int nRequestID, boolean bIsLast) {
        if (pRspInfo != null && pRspInfo.getErrorID() != 0) {
            System.out.printf("OnRspUserLogin ErrorID[%d] ErrMsg[%s]\n", pRspInfo.getErrorID(), pRspInfo.getErrorMsg());
            return;
        }
        System.out.println("Login success!!!");
        m_mdapi.SubscribeMarketData();     //订阅行情
    }

    /**
     * 订阅行情应答，调用SubscribeMarketData后，通过此接口返回。
     */
    @Override
    public void OnRspSubMarketData(CThostFtdcSpecificInstrumentField pSpecificInstrument, CThostFtdcRspInfoField pRspInfo, int nRequestID, boolean bIsLast) {
        if (pRspInfo != null && pRspInfo.getErrorID() != 0) {
            System.out.printf("OnRspSubMarketData ErrorID[%d] ErrMsg[%s]\n", pRspInfo.getErrorID(), pRspInfo.getErrorMsg());
            return;
        }
        System.out.println("InstrumentID：" + pSpecificInstrument.getInstrumentID());
    }

    /**
     * 深度行情处理异常值
     */
    public void DealTooMax(CThostFtdcDepthMarketDataField mddata) {
        double maxprice = 1e+15;
        double minprice = -1e+15;
        if ((mddata.getSettlementPrice() > maxprice) || (mddata.getSettlementPrice() < minprice)) {
            mddata.setSettlementPrice(0);
        }
        if ((mddata.getOpenPrice() > maxprice) || (mddata.getOpenPrice() < minprice)) {
            mddata.setOpenPrice(0);
        }
        if ((mddata.getHighestPrice() > maxprice) || (mddata.getHighestPrice() < minprice)) {
            mddata.setHighestPrice(0);
        }
        if ((mddata.getLowestPrice() > maxprice) || (mddata.getLowestPrice() < minprice)) {
            mddata.setLowestPrice(0);
        }
        if ((mddata.getPreDelta() > maxprice) || (mddata.getPreDelta() < minprice)) {
            mddata.setPreDelta(0);
        }
        if ((mddata.getCurrDelta() > maxprice) || (mddata.getCurrDelta() < minprice)) {
            mddata.setCurrDelta(0);
        }
        if ((mddata.getBidPrice1() > maxprice) || (mddata.getBidPrice1() < minprice)) {
            mddata.setBidPrice1(0);
        }
        if ((mddata.getAskPrice1() > maxprice) || (mddata.getAskPrice1() < minprice)) {
            mddata.setAskPrice1(0);
        }

    }

    /**
     * 深度行情通知，当SubscribeMarketData订阅行情后，行情通知由此推送。
     */
    @Override
    public void OnRtnDepthMarketData(CThostFtdcDepthMarketDataField pDepthMarketData) {
        DealTooMax(pDepthMarketData);
        StringBuilder mdlist = new StringBuilder();
        mdlist.append(pDepthMarketData.getTradingDay() + ',');
        mdlist.append(pDepthMarketData.getInstrumentID() + ',');
        mdlist.append(pDepthMarketData.getLastPrice() + ',');
        mdlist.append(pDepthMarketData.getPreSettlementPrice() + ',');
        mdlist.append(pDepthMarketData.getPreClosePrice() + ',');
        mdlist.append(pDepthMarketData.getPreOpenInterest() + ',');
        mdlist.append(pDepthMarketData.getOpenPrice() + ',');
        mdlist.append(pDepthMarketData.getHighestPrice() + ',');
        mdlist.append(pDepthMarketData.getLowestPrice() + ',');
        mdlist.append(pDepthMarketData.getVolume() + ',');
        mdlist.append(pDepthMarketData.getTurnover() + ',');
        mdlist.append(pDepthMarketData.getOpenInterest() + ',');
        mdlist.append(pDepthMarketData.getClosePrice() + ',');
        mdlist.append(pDepthMarketData.getSettlementPrice() + ',');
        mdlist.append(pDepthMarketData.getUpperLimitPrice() + ',');
        mdlist.append(pDepthMarketData.getLowerLimitPrice() + ',');
        mdlist.append(pDepthMarketData.getPreDelta() + ',');
        mdlist.append(pDepthMarketData.getCurrDelta() + ',');
        mdlist.append(pDepthMarketData.getUpdateTime() + ',');
        mdlist.append(pDepthMarketData.getUpdateMillisec() + ',');
        mdlist.append(pDepthMarketData.getBidPrice1() + ',');
        mdlist.append(pDepthMarketData.getBidVolume1() + ',');
        mdlist.append(pDepthMarketData.getAskPrice1() + ',');
        mdlist.append(pDepthMarketData.getAskVolume1() + ',');
        mdlist.append(pDepthMarketData.getAveragePrice());
        System.out.println(mdlist);
    }

}
